package com.milhouz.bomberrokon;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.MotionEvent;

import com.milhouz.bomberrokon.dialog.DialogId;
import com.milhouz.bomberrokon.dialog.EndRoundDialog;
import com.milhouz.bomberrokon.dialog.PauseMenuDialog;
import com.milhouz.bomberrokon.dialog.StartRoundDialog;
import com.milhouz.bomberrokon.engines.GameEngine;
import com.milhouz.bomberrokon.engines.GraphicEngine;
import com.milhouz.bomberrokon.engines.SoundEngine;
import com.milhouz.bomberrokon.events.BomberMoveEvent;
import com.milhouz.bomberrokon.events.DropBombEvent;
import com.milhouz.bomberrokon.events.EventManager;
import com.milhouz.bomberrokon.sprite.BomberSprite;
import com.stickycoding.Rokon.RokonActivity;

public class BomberSlashActivity extends RokonActivity {

	// --- Dev options
	public static final boolean DEBUG_MODE = true;
	public static final boolean SHOW_FPS = true;
	public static final int SCREEN_WIDTH = 480;
	public static final int SCREEN_HEIGHT = 320;

	private Context mContext;

	private static GraphicEngine mGraphicEngine;
	private static GameEngine mGameEngine;
	private static SoundEngine mSoundEngine;

	@Override
	public void onCreate() {
		mContext = this;
		// Initialize EventManager
		EventManager.init();
		// Instanciate engines
		mGameEngine = new GameEngine(this);
		mGraphicEngine = new GraphicEngine(this);
		mSoundEngine = new SoundEngine(this);
		// Attach engines each others
		mGameEngine.attachGraphicEngine(mGraphicEngine);
		mGameEngine.attachSoundEngine(mSoundEngine);
		mGraphicEngine.attachGameEngine(mGameEngine);
		mGraphicEngine.attachSoundEngine(mSoundEngine);
		mSoundEngine.attachGameEngine(mGameEngine);
		mSoundEngine.attachGraphicEngine(mGraphicEngine);
		// Create engines
		mGameEngine.createEngine();
		mGraphicEngine.createEngine();
		mSoundEngine.createEngine();
		// Now's a good time to run the GC.
		Runtime.getRuntime().gc();
	}

	@Override
	public void onLoad() {
		// Initialize the game data
		mGameEngine.loadEngine();
		// Load the Graphic Engine
		mGraphicEngine.loadEngine();
		// Load Sound engine
		mSoundEngine.loadEngine();
		// Now's a good time to run the GC.
		Runtime.getRuntime().gc();
	}

	@Override
	public void onLoadComplete() {
		// Set the background image or the background color or do nothing
		if (mGameEngine.getMapModel().getBackgroundFile() != null) {
			rokon.setBackground(mGraphicEngine.getBackground());
		} else if (mGameEngine.getMapModel().getBackgroundColor() != null) {
			String[] colors = mGameEngine.getMapModel().getBackgroundColor().split(",");
			rokon.setBackgroundColor(Float.valueOf(colors[0]), Float.valueOf(colors[1]), Float.valueOf(colors[2]));
		}
		// Show start round dialog
		Message.obtain(pHandler, DialogId.START_ROUND).sendToTarget();
	}

	@Override
	public void onGameLoop() {
		if (mGameEngine.getGameRound().isStarted()) {
			// Game engine working step and event processing
			mGameEngine.step();
			// Graphic engine working step and event processing
			mGraphicEngine.step();
			// Sound engine working step and event processing
			mSoundEngine.step();
			// Process Engines Events
			EventManager.processEvent(mGameEngine, mGraphicEngine, mSoundEngine);
		}
	}

	// ///////////////////////////////
	// KEYS CAPTURE
	// ///////////////////////////////
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == 19) {
			EventManager.pushEvent(new BomberMoveEvent(0, BomberSprite.DIRECTION_UP));
		} else if (keyCode == 20) {
			EventManager.pushEvent(new BomberMoveEvent(0, BomberSprite.DIRECTION_DOWN));
		} else if (keyCode == 21) {
			EventManager.pushEvent(new BomberMoveEvent(0, BomberSprite.DIRECTION_LEFT));
		} else if (keyCode == 22) {
			EventManager.pushEvent(new BomberMoveEvent(0, BomberSprite.DIRECTION_RIGHT));
		} else if (keyCode == KeyEvent.KEYCODE_MENU || keyCode == KeyEvent.KEYCODE_BACK) {
			// Display PAUSE Menu
			Message.obtain(pHandler, DialogId.PAUSE_ROUND).sendToTarget();
		} else if (keyCode == KeyEvent.KEYCODE_HOME) {
			rokon.pause();
			super.finish();
		}
		return true;
	}

	@Override
	public boolean onKeyUp(int keyCode, KeyEvent event) {
		if (keyCode != KeyEvent.KEYCODE_MENU || keyCode != KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_HOME) {
			EventManager.pushEvent(new BomberMoveEvent(0, BomberSprite.DIRECTION_STOP));
		}
		return true;
	}

	@Override
	public void onTouchUp(int x, int y, boolean hotspot) {
		EventManager.pushEvent(new DropBombEvent(0));
	}

	@Override
	public boolean onTrackballEvent(MotionEvent event) {
		int action = event.getAction();
		if (action == MotionEvent.ACTION_MOVE) {
			if (event.getY() < 0) { // Up
				EventManager.pushEvent(new BomberMoveEvent(0, BomberSprite.DIRECTION_UP));
			} else if (event.getY() > 0) { // Down
				EventManager.pushEvent(new BomberMoveEvent(0, BomberSprite.DIRECTION_DOWN));
			} else if (event.getX() < 0) { // Right
				EventManager.pushEvent(new BomberMoveEvent(0, BomberSprite.DIRECTION_LEFT));
			} else if (event.getX() > 0) {// Left
				EventManager.pushEvent(new BomberMoveEvent(0, BomberSprite.DIRECTION_RIGHT));
			}
		} else if (action == MotionEvent.ACTION_DOWN) {
			EventManager.pushEvent(new BomberMoveEvent(0, BomberSprite.DIRECTION_STOP));
		}
		return true;
	}

	// ///////////////////////////////
	// ANDROID SYSTEM
	// ///////////////////////////////
	@Override
	public void onRestart() {
		super.onRestart();
		rokon.unpause();
	}

	// ///////////////////////////////
	// Message Handler
	// ///////////////////////////////
	private Handler pHandler = new Handler() {
		@Override
		public void handleMessage(Message message) {
			// message.what is the second parameter in Message.obtain.
			switch (message.what) {
			case DialogId.START_ROUND:
				StartRoundDialog startDialog = new StartRoundDialog(mContext, mGameEngine.getGameRound());
				startDialog.show();
				break;
			case DialogId.PAUSE_ROUND:
				rokon.pause();
				PauseMenuDialog pauseDialog = new PauseMenuDialog(mContext);
				pauseDialog.show();
				break;
			case DialogId.END_ROUND:
				EndRoundDialog endRoundDialog = new EndRoundDialog(mContext, mGameEngine.getGameRound(), mGameEngine.getMapModel());
				endRoundDialog.show();
				break;
			}
		}

	};

	public Handler getHandler() {
		return pHandler;
	}

}